package com.block.datapush.special.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.block.common.constant.AppRspCodeConstant;
import com.block.common.enums.InfoTypeEnum;
import com.block.common.exception.NotifyExceptionService;
import com.block.common.service.IApplicationInfoService;
import com.block.common.service.IChannelCommonService;
import com.block.common.service.LogFactory;
import com.block.common.service.merchant.IMerchantThirdBaseInfoService;
import com.block.common.vo.ResponseVo;
import com.block.datapush.common.model.result.FilterHandlerResult;
import com.block.datapush.common.service.ISpecialDataFilterHandlerService;
import com.block.datapush.model.dto.ProtocolInfoEntity;
import com.block.datapush.model.result.SpePushResut;
import com.block.datapush.special.enums.OrderStatusEnum;
import com.block.datapush.special.service.IDataPushSelfSpecialService;
import com.block.datapush.special.service.ISpecialCostomInfoService;
import com.block.db.entity.*;
import com.block.db.mapper.*;
import com.block.sms.service.ISmsRecordService;
import org.slf4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.InputStream;
import java.net.URL;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 自采流量进行推送流程
 */
@Service
public class DataPushSelfSpecialService implements IDataPushSelfSpecialService {

    private static Logger log = LogFactory.getPushLog();

    @Resource
    SpecialCostomItemInfoMapper specialCostomItemInfoMapper;
    @Autowired
    ISpecialCostomInfoService specialCostomInfoService;
    @Autowired
    NotifyExceptionService notifyExceptionService;
    @Autowired
    ISpecialDataFilterHandlerService specialDataFilterHandlerService;
    @Autowired
    ISmsRecordService smsRecordService;
    @Resource
    MemberPushOrderInfoMapper memberPushOrderInfoMapper;
    @Resource
    SourcePushResultInfoMapper sourcePushResultInfoMapper;
    @Autowired
    IChannelCommonService channelCommonService;
    @Autowired
    IApplicationInfoService applicationInfoService;
    @Autowired
    IMerchantThirdBaseInfoService merchantThirdBaseInfoService;
    @Resource
    MerchantThirdProtocolInfoMapper merchantThirdProtocolInfoMapper;
    @Resource
    MemberExtInfoMapper memberExtInfoMapper;

    @Override
    public ResponseVo againCheckUser(Long uid) {

        MemberExtInfo memberExtInfo = memberExtInfoMapper.selectById(uid);

        SpePushResut spePushResut = null;
        if (ObjectUtil.isNotEmpty(memberExtInfo)){
            spePushResut = this.dataCheckHandle(memberExtInfo);
        }else{
            spePushResut = new SpePushResut();
            spePushResut.setPushSuccess(false);
        }

        return new ResponseVo(AppRspCodeConstant.SUCCESS, spePushResut);
    }

    /**
     * 数据撞库 流程
     *
     * @param memberExtInfo
     * @return
     */
    @Override
    public SpePushResut dataCheckHandle(MemberExtInfo memberExtInfo) {

        SpePushResut spePushResut = new SpePushResut();
        spePushResut.setPushSuccess(false);

        // 查询可推送的所有商户任务
        List<SpecialCostomItemInfo> costomItemInfoList = specialCostomItemInfoMapper.getNormalCanPushItmeInfoList();

        List<SpecialCostomItemInfo> canPushItemList = new ArrayList<>();
        // 第一遍循环，推送任务过滤，找出可以推送的任务
        for (SpecialCostomItemInfo itemInfo: costomItemInfoList){
            /**
             * 根据任务设置的条件
             * 以及，用户填写的资质
             * 判断该用户资质是否满足该任务
             */
            FilterHandlerResult handlerResult = specialDataFilterHandlerService.execCondiFilter(itemInfo, memberExtInfo);
            if (handlerResult.isSuccess()){
                // 任务满足条件，则添加到可推送列表
                canPushItemList.add(itemInfo);
            }
        }

        // 如果可推送列表为空，则返回撞库失败
        if (CollUtil.isEmpty(canPushItemList)){
            // 没有满足条件可推送的任
            spePushResut.setMessage("没有可推送的任务");
            return spePushResut;
        }

        // TODO: 2024/7/8 同步推送，需要改为异步推送
        for (SpecialCostomItemInfo itemInfo : canPushItemList) {
            try {
                spePushResut = specialCostomInfoService.checkUser(itemInfo, memberExtInfo);
                if (spePushResut.isPushSuccess()){
                    // 撞库成功，则返回机构相关信息

                    ChannelInfo channelInfoCache = channelCommonService.getChannelInfoCache(memberExtInfo.getChannelCode());
                    ApplicationInfo applicationInfo = applicationInfoService.getAppInfoByType(channelInfoCache.getAppType());
                    String apiUrl = applicationInfo.getApiUrl();
                    String pushOrderNo = spePushResut.getPushOrderNo();

                    String ownerProtocolUrl = StrUtil.format("{}page/user/newprotocol/{}.html", apiUrl, pushOrderNo);
                    spePushResut.setProtocolUrl(ownerProtocolUrl);

                    break;
                }
            }catch (Exception exception){
                exception.printStackTrace();
                notifyExceptionService.notifyException("","","","机构推送分流任务：" + memberExtInfo.getUid()+";"+itemInfo.getId(), exception);
            }
        }

        return spePushResut;
    }

    /**
     * 数据进件流程
     *
     * @param orderNo
     * @return
     */
    @Override
    public ResponseVo dataRegisterHandle(String orderNo) {

        try {
            /**
             * 推送的时候不判断商户的余额
             * 如果撞库成功，已经展示了商户的信息
             * 已经产生了消耗
             */
            SpePushResut spePushResut = specialCostomInfoService.registerUser(orderNo);


            return new ResponseVo(AppRspCodeConstant.SUCCESS, spePushResut);
        }catch (Exception exception){
            notifyExceptionService.notifyException("","","","机构推送异常：orderNo:" + orderNo, exception);
        }
        return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "", "进件异常");
    }



    /**
     * 1825281783263072258
     * @param orderNo
     * @return
     */
    @Override
    public ResponseVo getUrlOrderInfo(String orderNo) {

        SourcePushResultInfo pushResultInfo = sourcePushResultInfoMapper.selectById(orderNo);
        if (ObjectUtil.isEmpty(pushResultInfo)){
            return new ResponseVo(AppRspCodeConstant.DATA_INFO_NULL, "订单信息为空");
        }
        if (!StrUtil.equals(pushResultInfo.getStatus(), OrderStatusEnum.WAIT_APPROVE.getValue())){
            return new ResponseVo(AppRspCodeConstant.DATA_INFO_NULL, "订单状态错误");
        }

        MemberPushOrderInfo pushOrderInfo = memberPushOrderInfoMapper.getEnityByIdLock(pushResultInfo.getOrderNo());
        if (ObjectUtil.isEmpty(pushOrderInfo)){
            return new ResponseVo(AppRspCodeConstant.DATA_INFO_NULL, "推送订单信息为空");
        }

        // 订单超时
        boolean timeoutFlag = LocalDateTime.now().isAfter(pushOrderInfo.getCreateTime().plusMinutes(30L));
        if (timeoutFlag){
            return new ResponseVo(AppRspCodeConstant.SYS_EXCEPTION, "订单超时");
        }

        // 生成机构返回信息
        JSONObject returnObject = new JSONObject();
        returnObject.put("orderNo", String.valueOf(pushResultInfo.getId()));

        ChannelInfo channelInfoCache = channelCommonService.getChannelInfoCache(pushResultInfo.getChannelCode());
        ApplicationInfo applicationInfo = applicationInfoService.getAppInfoByType(channelInfoCache.getAppType());
        String apiUrl = applicationInfo.getApiUrl();

        String ownerProtocolUrl = StrUtil.format("{}page/user/newprotocol/{}.html", apiUrl, pushResultInfo.getOrderNo());
        returnObject.put("ownerProtocolUrl", ownerProtocolUrl);

        List<ProtocolInfoEntity> protocolList = new ArrayList<>();

        JSONObject dataInfo = new JSONObject();
        // 判断机构类型
        if (StrUtil.equals(pushOrderInfo.getInfoType(), InfoTypeEnum.APIS.getValue())){

            MerchantThirdBaseInfo thirdBaseInfo = merchantThirdBaseInfoService.selectEntityByOrderNo(pushOrderInfo.getPushId());

            dataInfo.put("productName", thirdBaseInfo.getProductName());
            dataInfo.put("compantName", thirdBaseInfo.getCompanyName());
            dataInfo.put("descInfo", "信用贷款");
            dataInfo.put("compantLogo", thirdBaseInfo.getCompanyLogo());

            dataInfo.put("maxLoanAmount", thirdBaseInfo.getMaxLoanAmount());
            dataInfo.put("maxRate", thirdBaseInfo.getMaxLoanRate());
            dataInfo.put("minRate", thirdBaseInfo.getMinLoanRate());

            List<MerchantThirdProtocolInfo> protocolInfoList = merchantThirdProtocolInfoMapper.selectListByThirdId(thirdBaseInfo.getId());

            List<ProtocolInfoEntity> resultList = protocolInfoList.stream().map(protocolInfo -> {
                ProtocolInfoEntity infoEntity = new ProtocolInfoEntity();
                infoEntity.setProtocolUrl(protocolInfo.getProtocolUrl());
                infoEntity.setProtocolName(protocolInfo.getProtocolName());

                return infoEntity;
            }).collect(Collectors.toList());

            protocolList.addAll(resultList);
        }else{
            // 查询机构信息
            SpecialCostomInfo specialCostomInfo = specialCostomInfoService.getById(pushOrderInfo.getInfoId());

            dataInfo.put("productName", specialCostomInfo.getProductName());
            dataInfo.put("compantName", specialCostomInfo.getCompanyName());
            dataInfo.put("descInfo", "信用贷款");
            dataInfo.put("compantLogo", specialCostomInfo.getCompanyLogo());

            dataInfo.put("maxLoanAmount", specialCostomInfo.getMaxLoanAmount());
            dataInfo.put("maxRate", specialCostomInfo.getMaxRate());
            dataInfo.put("minRate", specialCostomInfo.getMinRate());

            ProtocolInfoEntity infoEntity = new ProtocolInfoEntity();
            infoEntity.setProtocolUrl(ownerProtocolUrl);
            infoEntity.setProtocolName("授权协议");
            protocolList.add(infoEntity);
        }

        returnObject.put("otherProtocolUrl", protocolList);
        returnObject.put("dataInfo", dataInfo);

        return new ResponseVo(AppRspCodeConstant.SUCCESS, returnObject);
    }

    /**
     * 单独推送某个机构
     * 手动/代码推送
     * @param costomInfo
     * @param memberExtInfo
     * @return
     */
    @Override
    public ResponseVo dataPushSingleCostomInfo(SpecialCostomInfo costomInfo, MemberExtInfo memberExtInfo) {

        // 查询可用的机构信息
        List<SpecialCostomItemInfo> enableEntityList =
                specialCostomItemInfoMapper.getEnableEntityListByInfoId(costomInfo.getId());
        if (CollUtil.isEmpty(enableEntityList)){
            return new ResponseVo(AppRspCodeConstant.DATA_INFO_NULL, "没有可推送的任务", "");
        }

        SpePushResut result = null;
        try {
            for (SpecialCostomItemInfo itemInfo: enableEntityList){
                FilterHandlerResult handlerResult = specialDataFilterHandlerService.execCondiFilter(itemInfo, memberExtInfo);

                if (handlerResult.isSuccess()){
                    result = specialCostomInfoService.checkAndRegisterUser(itemInfo, memberExtInfo);
                    if (result.isPushSuccess()){
                        break;
                    }
                }else{
                    result = new SpePushResut();
                    result.setPushSuccess(false);
                    result.setMessage(handlerResult.getMessage());
                }
            }
        }catch (Exception exception){
            exception.printStackTrace();
            return new ResponseVo(AppRspCodeConstant.DATA_INFO_NULL, "操作异常："+exception.getMessage(), "");
        }

        if (ObjectUtil.isEmpty(result)){
            return new ResponseVo(AppRspCodeConstant.DATA_INFO_NULL, "推送结果为空", "");
        }

        if (!result.isPushSuccess()){
            return new ResponseVo(AppRspCodeConstant.DATA_INFO_NULL, "推送失败："+result.getMessage(), "");
        }

        return new ResponseVo(AppRspCodeConstant.SUCCESS, result);
    }



}
